package rpc.core.plugin;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import rpc.core.plugin.impl.proxy.ServiceProxy;
import rpc.utils.TypeSafe;

/*********
 *
 *
 *@author 197
 *@date 2020/7/29 17:30
 *
 **/


public interface ServicePlugin extends DumpPlugin {

  Logger logger = LoggerFactory.getLogger(ServicePlugin.class);

  /***
   * 初始化
   */
  void init();

  /***
   * 返回flowName
   * @return 返回name
   */
  Set<String> getFlowName();

  default int intConfig(Environment environment, String key, int dv) {
    return TypeSafe.anyToInt(environment.getProperty(key, String.valueOf(dv)));
  }

  /***
   * 关闭
   */
  void close();

  default List<String> getClassNameList(Environment environment) {
    List<String> classNames = new ArrayList<>(0);
    String basePath = environment.getProperty("rpc.flow.basePath");
    if (StringUtils.isBlank(basePath)) {
      logger.info("basePath is null return");
      return classNames;
    }
    final String basePathTmp = basePath.replaceAll("\\.", "/") + getSelfDir();
//    logger.info("basePathTmp:{}", basePathTmp);
    URL resource = this.getClass().getClassLoader().getResource(basePathTmp);
    if (Objects.isNull(resource)) {
      logger.error("dbFlow path is error:{}", environment.getProperty("rpc.flow.basePath"));
      return classNames;
    }
//    logger.info("basePath:{}", basePath);
    Collection<File> files = FileUtils
        .listFiles(new File(resource.getFile()), new String[]{"class"}, true);

    String separator = "/".equals(File.separator) ? "/" : "\\\\";
    classNames = files.stream().map(File::getAbsolutePath)
        .map(p -> p.replaceAll(separator, "."))
        .map(path -> path.substring(path.indexOf(basePath)))
        .map(p -> p.substring(0, p.length() - 6)).collect(Collectors.toList());
    return classNames;

  }

  default String getSelfDir() {
    return "/" + this.getClass().getSimpleName().replace("ServicePlugin", "").toLowerCase();
  }
//
//  /****
//   *  调用方法
//   * @param flowName  flow名称
//   * @param req 入参
//   * @return FlowRes
//   */
//  default CompletableFuture<FlowRes> invoke(String flowName, FlowReq req) {
//    ServiceProxy serviceProxy = getFlowServiceProxy().get(flowName);
//    if (Objects.nonNull(serviceProxy)) {
//      CompletableFuture<FlowRes> completableFuture = serviceProxy.invoke(req);
//      completableFuture.exceptionally((e) -> {
//        logger.error("exception:{} stackTrace:{}", e.getMessage(), ExceptionUtils.getTrace(e));
//        return new FlowRes().fail(-999817).msg(e.getMessage());
//      });
//      return completableFuture;
//    }
//    return CompletableFuture.completedFuture(new FlowRes().fail(-999816).msg("flowName:" + flowName + ",no impl"));
//  }

  /*****
   *  获取所有flow
   * @return flow集合与实现
   */
  Map<String, ServiceProxy> getFlowServiceProxy();
}
